# encoding: utf-8

import datetime, cgi
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
from pytz.gae import pytz
import security, config, svrutil

class entity_photo(db.Model):
	caption=db.StringProperty()
	image_type=db.StringProperty()

class entity_year(db.Model):
	months=db.IntegerProperty()

class update_photos(webapp.RequestHandler):
	def post(self):
		'''
		更新指定日期的照片数据
		'''
		svrutil.response_begin(self.response)
		user=cgi.escape(self.request.get('user'))
		pwd=cgi.escape(self.request.get('pwd'))
		if not security.verify_user(user,pwd):
			self.response.out.write('<p>用户名或密码错误</p>')
			svrutil.response_end(self.response)
			return
		try:
			sdt=self.request.get('date')
			dt=datetime.datetime(int(sdt[:4]),int(sdt[4:6]),int(sdt[6:]))
			if dt.year<=2000:
				self.response.out.write('<p>日期错误，必须在2000年之后</p>')
				svrutil.response_end(self.response)
				return
			imgcount=int(self.request.get('imgcount'))
			if imgcount<1:
				self.response.out.write('<p>需要更新的照片数量为零</p>')
				svrutil.response_end(self.response)
				return
			if imgcount>config.MAX_PHOTO_PER_DAY:
				self.response.out.write('<p>照片数量超过上限，每天最多只允许上传%d张照片</p>'%config.MAX_PHOTO_PER_DAY)
				svrutil.response_end(self.response)
				return
			self.response.out.write("<ul>")
			for i in xrange(imgcount):
				fname='%s-%02d'%(sdt,i)
				cap=self.request.get('imgcap%d'%i)
				photo=entity_photo(key_name=fname,caption=cap,image_type='jpg')
				photo.put()
				self.response.out.write("<li><span style='margin-right:2em;'>%s</span>%s</li>"%(fname.encode('utf8'),cap.encode('utf8')))
			self.response.out.write("</ul>")
			## 更新日期索引
			yeardata=db.get(db.Key.from_path('entity_year',str(dt.year)))
			if yeardata is None:
				yeardata=entity_year(key_name=str(dt.year),months=0)
				self.response.out.write("<p>创建年索引:%d</p>"%dt.year)
			flag=1<<dt.month
			if 0==(yeardata.months&flag):
				yeardata.months|=flag
				yeardata.put()
				self.response.out.write("<p style='margin-left:2em;'>更新%d月索引</p>"%dt.month)
		except:
			self.response.out.write('<p>数据库错误,更新失败</p>')			
		finally:
			svrutil.response_end(self.response)

class read_photos(webapp.RequestHandler):

	def get(self):
		## 显示当周的照片
		tz=pytz.timezone(config.USER_TIMEZONE) 
		today=datetime.datetime.now(tz)		
		yeardata=self.__fetch_yeardata()
		monthdata=self.__fetch_monthdata(today,today)
		photodata=self.__fetch_weekdata(today)
		import photodiary.page_index
		photodiary.page_index.build_page(self.response.out,today,today,yeardata,monthdata,photodata)

	def post(self):
		## 显示指定日期的一周照片
		tz=pytz.timezone(config.USER_TIMEZONE) 
		today=datetime.datetime.now(tz)		
		sdt=self.request.get('date','no-date')
		try:
			if len(sdt)==6:
				date=datetime.datetime(int(sdt[:4]),int(sdt[4:6]),1)
			elif len(sdt)==8:
				date=datetime.datetime(int(sdt[:4]),int(sdt[4:6]),int(sdt[6:8]))
			else:
				raise Exception
		except:
			svrutil.response_begin(self.response)
			self.response.out.write("<h2>日期错误:%s</h2>"%sdt.encode('utf8'))
			svrutil.response_end(self.response)
			return
		yeardata=self.__fetch_yeardata()
		monthdata=self.__fetch_monthdata(date,today)
		photodata=self.__fetch_weekdata(date)
		import photodiary.page_index
		photodiary.page_index.build_page(self.response.out,today,date,yeardata,monthdata,photodata)

	def __fetch_weekdata(self, date):
		'''
		读取指定日期的一周数据
		返回: [(date_of_Monday,photo_list),(date_of_Tuesday,photo_list)...(date_of_Sunday,photo_list)]
		其中photo_list为：[(photo0,caption0),(photo1,caption1)...]
		'''
		ret=[]
		## Monday is 0, Sunday is 6
		dt=date-datetime.timedelta(days=date.weekday())
		delta=datetime.timedelta(days=1)
		for i in xrange(7):
			sd=dt.strftime('%Y%m%d')
			query=db.Query(entity_photo)
			query.filter('__key__ >=',db.Key.from_path('entity_photo','%s-00'%sd))
			query.filter('__key__ <',db.Key.from_path('entity_photo','%s-%02d'%(sd,config.MAX_PHOTO_PER_DAY)))
			query.order('__key__')
			results=query.fetch(config.MAX_PHOTO_PER_DAY)
			if len(results):
				li=[]
				ret.append((dt,li))
				for photo in results:
					li.append(('%s.%s'%(photo.key().name(),photo.image_type),photo.caption))
			else:
				ret.append((dt,None))
			dt+=delta
		return ret

	def __fetch_monthdata(self, date, today):
		'''
		获取某月的照片数据
		'''
		ret=[]
		if today is None:
			tz=pytz.timezone(config.USER_TIMEZONE) 
			today=datetime.datetime.now(tz)
		dt=datetime.datetime(date.year,date.month,1)
		dt-=datetime.timedelta(days=dt.weekday())
		delta=datetime.timedelta(7)
		ndt=dt+delta
		itoday=today.year*10000+today.month*100+today.day
		idate=date.year*10000+date.month*100+date.day
		idt=dt.year*10000+dt.month*100+dt.day
		idt2=ndt.year*10000+ndt.month*100+ndt.day
		while dt.month<=date.month:
			# check if current week
			if itoday>=idt and itoday<idt2:
				current=True
			else:
				current=False
			# check if selected week
			if idate>=idt and idate<idt2:
				selected=True
			else:
				selected=False
			query=db.Query(entity_photo)
			query.filter('__key__ >=',db.Key.from_path('entity_photo','%d-00'%idt))
			query.filter('__key__ <',db.Key.from_path('entity_photo','%d-00'%idt2))
			ret.append((dt,query.count(),selected,current))
			dt=ndt
			ndt+=delta
			idt=idt2
			idt2=ndt.year*10000+ndt.month*100+ndt.day
		return ret

	def __fetch_yeardata(self):
		'''
		获取某年的照片数据
		'''
		query=entity_year.all()
		query.order('__key__')
		results=query.fetch(100) 
		ret=[]
		for ydata in results:
			ret.append((int(ydata.key().name()),ydata.months))
		return ret;

class build_date_index(webapp.RequestHandler):
	def get(self):
		'''
		为所有照片创建日期索引,只用于数据维护的需要
		'''
		query=entity_year.all()
		query.order('__key__')
		allyears=query.fetch(100) 
		query=entity_photo.all()
		for yitem in allyears:
			year=yitem.key().name()
			query.filter('__key__ >=',db.Key.from_path('entity_photo','%s0101-00'%year))
			query.filter('__key__ <',db.Key.from_path('entity_photo','%s1231-%02d'%(year,config.MAX_PHOTO_PER_DAY)))
			query.order('__key__')
			results=query.fetch(1000)
			cur_year=''
			yeardata=None
			needsave=False
			svrutil.response_begin(self.response)
			for photo in results:
				name=photo.key().name()
				year=name[:4]
				month=int(name[4:6])
				if year!=cur_year:
					if yeardata and needsave:
						yeardata.put()
						yeardata=None
						needsave=False
					cur_year=year
					yeardata=db.get(db.Key.from_path('entity_year',cur_year))
					if yeardata is None:
						yeardata=entity_year(key_name=cur_year,months=0)
						self.response.out.write("<p>创建年索引:%s</p>"%cur_year.encode('utf8'))
				flag=1<<month
				if 0==(yeardata.months&flag):
					yeardata.months|=flag
					needsave=True
					self.response.out.write("<p style='margin-left:2em;'>更新%d月索引</p>"%month)
			if yeardata and needsave:
				yeardata.put()
		self.response.out.write("<p>索引更新成功<p>")
		svrutil.response_end(self.response)

app=webapp.WSGIApplication([('/photodiary/index.html',read_photos),('/photodiary/update.html',update_photos),('/photodiary/dateindex.html',build_date_index)])

if __name__=='__main__':
	run_wsgi_app(app)

